from sqlalchemy import Column, String, Text, UniqueConstraint, Integer, ForeignKey, Boolean
from sqlalchemy.orm import relationship
from ..database import Base
from utils.id_util import generate_id
from .role_permission_do import RolePermissionModel
from .role_do import RoleModel

class PermissionModel(Base):
    __tablename__ = "permissions"

    id = Column(String, primary_key=True, default=generate_id, index=True)
    name = Column(String, unique=True, index=True, nullable=False)
    description = Column(Text, nullable=True)
    endpoint = Column(String, nullable=False)
    method = Column(String, nullable=False)
    title = Column(String, nullable=True)
    # UI related fields
    component = Column(String, nullable=True)
    icon = Column(String, nullable=True)
    order = Column(Integer, nullable=True)
    badgeType = Column(String, nullable=True)
    badgeVariants = Column(String, nullable=True)
    redirect = Column(String, nullable=True)
    noBasicLayout = Column(Boolean, default=False, nullable=False)
    hideInMenu = Column(Boolean, default=False, nullable=False)
    hideInTab = Column(Boolean, default=False, nullable=False)
    hideInBreadcrumb = Column(Boolean, default=False, nullable=False)
    hideChildrenInMenu = Column(Boolean, default=False, nullable=False)
    keepAlive = Column(Boolean, default=True, nullable=False)
    affixTab = Column(Boolean, default=False, nullable=False)
    openInNewWindow = Column(Boolean, default=False, nullable=False)
    permissionType = Column(String, nullable=False)
    
    # for hierarchy
    parent_id = Column(String, ForeignKey("permissions.id"), nullable=True)
    children = relationship("PermissionModel", back_populates="parent")
    parent = relationship("PermissionModel", back_populates="children", remote_side=[id])


    role_permissions = relationship("RolePermissionModel", backref="permission", cascade="all, delete-orphan")
    roles = relationship("RoleModel", secondary="role_permissions", viewonly=True)

    __table_args__ = (UniqueConstraint('endpoint', 'method', name='_endpoint_method_uc'),)

    def __repr__(self):
        return f"<Permission(id={{self.id}}, name='{self.name}', endpoint='{self.endpoint}', method='{self.method}')>"

    def to_dict_tree(self, with_children=True):
        data = {
            "id": self.id,
            "name": self.name,
            "description": self.description,
            "endpoint": self.endpoint,
            "method": self.method,
            "component": self.component,
            "icon": self.icon,
            "order": self.order,
            "badgeType": self.badgeType,
            "badgeVariants": self.badgeVariants,
            "redirect": self.redirect,
            "parent_id": self.parent_id,
            "noBasicLayout": self.noBasicLayout,
            "hideInMenu": self.hideInMenu,
            "hideInTab": self.hideInTab,
            "hideInBreadcrumb": self.hideInBreadcrumb,
            "hideChildrenInMenu": self.hideChildrenInMenu,
            "keepAlive": self.keepAlive,
            "affixTab": self.affixTab,
            "openInNewWindow": self.openInNewWindow,
            "permissionType": self.permissionType,
        }
        if with_children and self.children:
            data["children"] = [child.to_dict() for child in self.children]
        return data

    def to_dict(self, with_children=True):
        data = {
            "id": self.id,
            "name": self.name,
            "description": self.description,
            "endpoint": self.endpoint,
            "method": self.method,
            "component": self.component,
            "icon": self.icon,
            "order": self.order,
            "badgeType": self.badgeType,
            "badgeVariants": self.badgeVariants,
            "redirect": self.redirect,
            "parent_id": self.parent_id,
            "noBasicLayout": self.noBasicLayout,
            "hideInMenu": self.hideInMenu,
            "hideInTab": self.hideInTab,
            "hideInBreadcrumb": self.hideInBreadcrumb,
            "hideChildrenInMenu": self.hideChildrenInMenu,
            "keepAlive": self.keepAlive,
            "affixTab": self.affixTab,
            "openInNewWindow": self.openInNewWindow,
            "permissionType": self.permissionType,
        }
        return data

    def to_menu_dict(self):
        """
        Converts the permission object to a dictionary format suitable for menus.
        """
        menu_dict = {
            "id": self.id,
            "name": self.name,
            "endpoint": self.endpoint,
            "component": self.component,
            "icon": self.icon,
            "order": self.order,
            "badgeType": self.badgeType,
            "badgeVariants": self.badgeVariants,
            "redirect": self.redirect,
            "parent_id": self.parent_id,
            "noBasicLayout": self.noBasicLayout,
            "hideInMenu": self.hideInMenu,
            "hideInTab": self.hideInTab,
            "hideInBreadcrumb": self.hideInBreadcrumb,
            "hideChildrenInMenu": self.hideChildrenInMenu,
            "keepAlive": self.keepAlive,
            "affixTab": self.affixTab,
            "openInNewWindow": self.openInNewWindow,
            "permissionType": self.permissionType,
        }
        if self.children:
            menu_dict["children"] = [child.to_menu_dict() for child in self.children]
        return menu_dict